/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package lc3vm;

import java.io.FileNotFoundException;

/**
 *
 * @author dave
 */
public class Compilador {

    private static int numLinea = 0, desplazamiento = 0, origen = 0, direccionActual = 0;
    
    
    //Método compilar, cambia de lenguaje ASM a BIN
    public static void compilar(String linea) throws FileNotFoundException {


        String binario, token;
        /*
        String[] instrucciones =
            {
              "ADD", "AND", "BR", "JMP", "LD", "LDI", "LDR", "LEA", "NOT", "RET",
              "ST", "STI", "STR", "TRAP", "SUB", "MUL", "DIV", "BRnzp", "BRn", "BRz",
              "BRp", "BRnz", "BRzp", "BRnp"
            };*/

        String[] sym = Metodos.leer("test.sym");
        //Se utiliza un StringBuffer para poder insertar un String dentro de otro
        StringBuffer temp = null;
        boolean conEtiqueta = true;



       System.out.println(linea);

        //Eliminar comentarios, si hay
        if(linea.contains(";"))
            linea = linea.substring(0, linea.indexOf(";"));
       System.out.println(linea.split(" ")[1]);

        token = linea.split(" ")[0];

        if(token.equals(".ORIG")) {
            origen = Convertidor.hexInt(linea.split(" ")[1]);
            linea = linea.replaceAll(linea, Convertidor.hexBin(linea.split(" ")[1]));
        }


        direccionActual = numLinea + origen;

        for(int x =0; x < sym.length; x++)
            if(token.equals(sym[x].split(" ")[0]))
            linea = linea.replaceAll(sym[x].split(" ")[0], "");

        /*
        
        //for(int i =0; i < instrucciones.length; i++) {
        for(int i =0; i < instrucciones.length; i++) {
            if(token.matches(instrucciones[i]) || token.matches(".ORIG")) {
                System.out.println(token  +"NoTiene etiqueta");
                conEtiqueta = false;
            }

        }*/
        //}
        /*
        if(conEtiqueta){
            linea = linea.replaceAll(token,"");
        System.out.println(token + "  Este es el token!!!!!!!!!!!!!!!!!1");
        }    //Metodos.escribirBinario(token + " " + Integer.toHexString(direccionActual), "test.sym");
             */
        



        /*
        if(conEtiqueta) {
            linea.replaceAll(token, "");
            Memoria.getLinea(numLinea).setEtiqueta(token);
        }
         * */



        //Eliminar espacios y comas

        binario = linea;

        //Reemplazo de nemónicos por su respectivo opcode
        binario = binario.replaceAll("ADD", "0001");
        binario = binario.replaceAll("AND", "0101");
        binario = binario.replaceAll("SUB", "0100");
        binario = binario.replaceAll("BR", "0000");
        binario = binario.replaceAll("JMP", "1100000");
        binario = binario.replaceAll("LD", "0010");
        binario = binario.replaceAll("LDI", "1010");
        binario = binario.replaceAll("LDR", "0110");
        binario = binario.replaceAll("LEA", "1110");
        binario = binario.replaceAll("NOT", "1001");
        binario = binario.replaceAll("RET", "1100000111000000");
        binario = binario.replaceAll("ST", "0011");
        binario = binario.replaceAll("STI", "1011");
        binario = binario.replaceAll("STR", "0111");
        binario = binario.replaceAll("TRAP", "11110000");
        
        binario = binario.replaceAll("MUL", "1000");
        binario = binario.replaceAll("DIV", "1101");


        //Reemplazo de números de registros
        binario = binario.replaceAll("R0", "000");
        binario = binario.replaceAll("R1", "001");
        binario = binario.replaceAll("R2", "010");
        binario = binario.replaceAll("R3", "011");
        binario = binario.replaceAll("R4", "100");
        binario = binario.replaceAll("R5", "101");
        binario = binario.replaceAll("R6", "110");
        binario = binario.replaceAll("R7", "111");

        binario = binario.replaceAll(" ", "");
        binario = binario.replaceAll(",", "");

        //Inicialización de temp
        temp = new StringBuffer(binario);

        //Verificación de instrucciones diádicas AND y ADD
        if(linea.contains("AND") || linea.contains("ADD") || linea.contains("SUB") || linea.contains("MUL") || linea.contains("DIV")) {
            //Verificar si contiene operadores inmediatos
            if(linea.contains("#") || linea.contains("x") || linea.contains("b")) {
                temp.insert(10, "1");
                System.out.println(temp.toString());
                System.out.println(Integer.parseInt(temp.toString().substring(12))+"***************************+");
                System.out.println(Convertidor.decBin5(Integer.parseInt(temp.toString().substring(12)))+"********************************");
                temp = new StringBuffer(temp.toString().replaceAll(temp.toString().substring(11), Convertidor.decBin5(Convertidor.decInt(temp.toString().substring(12)))));
            } else {
                temp.insert(10, "000");

            }

        }

        //Verificación de instrucción BR
        if(linea.contains("BR")) {

            if(linea.contains("p"))
                temp.replace(0, temp.length(), temp.toString().replaceAll("p", "1"));
            else
                temp.insert(4, "0");

            if(linea.contains("z"))
                temp.replace(0, temp.length(), temp.toString().replaceAll("z", "1"));
            else
                temp.insert(4, "0");

            if(linea.contains("n"))
                temp.replace(0, temp.length(), temp.toString().replaceAll("n", "1"));
            else
                temp.insert(4, "0");

            for(int i = 0; i < sym.length; i++)
                if(sym[i].split(" ")[0].equals(temp.toString().substring(7))) {
                    desplazamiento = Convertidor.hexInt(sym[i].split(" ")[1]) - direccionActual  ;
                    System.out.println(desplazamiento+" aki va");
                    temp = new StringBuffer(temp.toString().replaceAll(sym[i].split(" ")[0], Convertidor.decBin9(desplazamiento)));
                }
        }

        //Verificación de NOT
        if(linea.contains("NOT")) {
            temp.insert(temp.length(), "11111");
        }

        //
        if(linea.contains("RET")) {
            temp.insert(temp.length(), "00011100000");
        }

        if(linea.contains("JMP")) {
            temp.insert(temp.length(), "000000");
        }

        if(linea.contains("LD") || linea.contains("ST") || linea.contains("LEA")){
            for(int i = 0; i < sym.length; i++)
                if(sym[i].split(" ")[0].equals(temp.toString().substring(7))) {
                    desplazamiento = Convertidor.hexInt(sym[i].split(" ")[1]) - direccionActual  ;
                    System.out.println(desplazamiento+" aki va");
                    temp = new StringBuffer(temp.toString().replaceAll(sym[i].split(" ")[0], Convertidor.decBin9(desplazamiento)));
                }
        }

        if(linea.contains("TRAP")) {
            temp = new StringBuffer(temp.toString().replaceAll(temp.substring(8), Convertidor.hexBin8(temp.substring(8))));
        }




        //Pasar el temp a String y ponerlo al String binario
        binario = temp.toString();

        if(!binario.equals("") && !binario.startsWith("."))
            numLinea++;

        
        System.out.println(binario+"binario");
        Metodos.escribirBinario(binario);


    }

    public static void analizar(String linea) throws FileNotFoundException {


        String token;
        String[] instrucciones =
            {
              "ADD", "AND", "BR", "JMP", "LD", "LDI", "LDR", "LEA", "NOT", "RET",
              "ST", "STI", "STR", "TRAP", "SUB", "MUL", "DIV", "BRnzp", "BRn", "BRz",
              "BRp", "BRnz", "BRzp", "BRnp"
            };

        token = linea.split(" ")[0];

        boolean conEtiqueta = true;


        //Eliminar comentarios, si hay
        if(linea.contains(";"))
            linea = linea.substring(0, linea.indexOf(";"));
        

        if(linea.split(" ")[0].equals(".ORIG"))
            origen = Convertidor.hexInt(linea.split(" ")[1]);
        //System.out.println(linea.split(" ")[1]);
        direccionActual = numLinea + origen;

        token = linea.split(" ")[0];

        for(int i =0; i < instrucciones.length; i++) {
            if(token.matches(instrucciones[i]) || token.matches(".ORIG")) {
                System.out.println(token  +"NoTiene etiqueta");
                conEtiqueta = false;
            }

        }
        
        if(conEtiqueta) {
             Metodos.escribirEtiquetas(token + " " + Integer.toHexString(direccionActual));
        }

        if(!linea.startsWith("."))
            numLinea++;
    }

    public static void reiniciarLinea() {
        numLinea = 0;
    }

}
